﻿#include "Timer.h"


#if _WIN32

#include <winsock2.h>
#define poll WSAPoll
#pragma comment(lib, "ws2_32.lib")

#else
#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <signal.h>
#include <poll.h>
#include <sys/select.h>
#endif

#define TIMEOUT 100

namespace LH {
    TimerThread::TimerThread() {
        //std::thread t{ [this]() {run(); } };
        //m_thread.swap(t);
        m_thread = std::thread{[this]() { run(); }};
    }

    TimerThread::~TimerThread() {
        m_quit.store(true);
        if (m_thread.joinable()) {
            m_thread.join();
        }
    }

    void TimerThread::run() {
        m_quit.store(false);
        while (!m_quit.load()) {
            // 当前时间点
            auto tp = std::chrono::steady_clock::now();
            // 执行当前定时器任务
            if (this->fireTimer(tp)) {
                // 更新时间点
                tp = std::chrono::steady_clock::now();
            }
            // 计算超时
            auto timeout = calculateTimeout(tp);
            if (timeout == -1 || timeout > TIMEOUT) timeout = TIMEOUT;

            // windows上sleep休眠精度不够，需要利用系统API进行相关操作
            // std::this_thread::sleep_for(std::chrono::milliseconds{ timeout });
            // (void)poll(nullptr, 0, TIMEOUT);
            {
                struct timeval tv{};
                tv.tv_sec = 0;  // 秒  1S = 1000000us
                tv.tv_usec = TIMEOUT * 1000;  // 微妙
                (void)select(1, nullptr, nullptr, nullptr, &tv);
            }
        }
    }
}
